﻿
/*
 * mathematical methods
 */
double PI = 3.141592654;

int abs( int x ) {
  if ( x < 0 )
    return -x;
  else
    return x;
}

long abs( long x ) {
  if ( x < 0 )
    return -x;
  else
    return x;
}

double abs( double x ) {
  if ( x < 0 )
    return -x;
  else
    return x;
}

int min( int x, int y ) {
  if ( x < y )
    return x;
  else
    return y;
}

long min( long x, long y ) {
  if ( x < y )
    return x;
  else
    return y;
}

double min( double x, double y ) {
  if ( x < y )
    return x;
  else
    return y;
}

int max( int x, int y ) {
  if ( x > y )
    return x;
  else
    return y;
}

long max( long x, long y ) {
  if ( x > y )
    return x;
  else
    return y;
}

double max( double x, double y ) {
  if ( x > y )
    return x;
  else
    return y;
}

native double exp( double x );

native double log( double x );

native double log10( double x );

/*
 * trigonometriske metoder
 */
native double sin( double x );

native double asin( double x );

native double sinh( double x );

native double cos( double x );

native double acos( double x );

native double cosh( double x );

native double tan( double x );

native double atan( double x );

native double tanh( double x );

native double atan2( double x, double y );

//-----

native double pow( double x, double y );

// DocJava: Rekursion: Eksponentiering
int pow( int x, int y ) {
  if ( y < 0 )
    throwRuntimeError( "ParameterOutOfBounds", "y", "" + y );

  if ( y == 0 )
    return 1;
  else {
    int halfPow = pow( x, y / 2 );
    int fullPow = halfPow * halfPow;
      
    if ( y % 2 == 1 )
      fullPow *= x;
      
    return fullPow;
  }
}

// DocJava: Rekursion: Eksponentiering
long pow( long x, long y ) {
  if ( y < 0L )
    throwRuntimeError( "ParameterOutOfBounds", "y", "" + y );

  if ( y == 0L )
    return 1L;
  else {
    long halfPow = pow( x, y / 2 );
    long fullPow = halfPow * halfPow;
      
    if ( y % 2 == 1 )
      fullPow *= x;
      
    return fullPow;
  }
}

double sqr( double x ) {
  return x * x;
}

int sqr( int x ) {
  return x * x;
}

long sqr( long x ) {
  return x * x;
}

native double sqrt( double x );

// http://en.wikipedia.org/wiki/Integer_square_root
int sqrt( int n ) {
  if ( n < 0 )
    throwRuntimeError( "CannotTakeSquareRootOf", "" + n );

  if ( n == 0 )
    return 0;

  double previous;
  double current = n;
  
  do {
    previous = current;
    current = ( previous + n / previous ) / 2.0;
  } while ( previous - current >= 1.0 );
  
  return (int) floor( current );
}

// http://en.wikipedia.org/wiki/Integer_square_root
long sqrt( long  n ) {
  if ( n < 0 )
    throwRuntimeError( "CannotTakeSquareRootOf", "" + n );

  if ( n == 0 )
    return 0;

  double previous;
  double current = n;
  
  do {
    previous = current;
    current = ( previous + n / previous ) / 2.0;
  } while ( previous - current >= 1.0 );
  
  return (long) floor( current );
}

int sign( long value ) {
  if ( value < 0 )
    return -1;
  else if ( value > 0 )
    return 1;
  else
    return 0;
}

native double ceil( double x );

native double floor( double x );

native int round( double x );

native double round( double x, int digits );

double toDegrees( double radians ) {
  return ( 180.0 / PI ) * radians;
}

double toRadians( double degrees ) {
  return ( PI / 180.0 ) * degrees;
}

// formating
String format( double value, int post ) {
  return format( value, 0, post, false );
}

String format( double value, int pre, int post ) {
  return format( value, pre, post, false );
}

String format( double value, int post, boolean thousands ) {
  return format( value, 0, post, thousands );
}

native String format( double value, int pre, int post, boolean thousands );
